/* gcc -g -Wall -Wextra -Wshadow -o enesim_cairo enesim_cairo.c `pkg-config --cflags --libs enesim cairo` -lm */

#include <math.h>
#include <sys/time.h>

#include <cairo.h>

#include <Enesim.h>

#define CAIRO_BEGIN(w, h) 						\
	cairo_surface_t *s; 						\
	cairo_t *cr; 							\
	double t0; 							\
	double t1; 							\
	s = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h); 	\
	cr = cairo_create(s); 						\
	t0 = _time_get()

#define CAIRO_END(f) 							\
	t1 = _time_get(); 						\
	printf("cairo: %E\n", t1 - t0); 				\
	cairo_destroy(cr); 						\
	cairo_surface_write_to_png(s, #f "_cairo.png"); 		\
	cairo_surface_destroy(s)

#define ENESIM_BEGIN(w, h) 						\
	Enesim_Surface *s; 						\
	Enesim_Renderer *rc; 						\
	double t0; 							\
	double t1; 							\
	s = enesim_surface_new(ENESIM_FORMAT_ARGB8888, w, h); 		\
	t0 = _time_get()

#define ENESIM_END(f) 							\
	Enesim_Log *error = NULL; 					\
	Enesim_Buffer *b;						\
	if (!enesim_renderer_draw(rc, s, ENESIM_ROP_FILL, NULL, 0, 0,	\
		&error)) 						\
		enesim_log_dump(error); 				\
	t1 = _time_get(); 						\
	printf("enesim: %E\n", t1 - t0); 				\
	b = enesim_surface_buffer_get(s);				\
	enesim_image_file_save(#f "_enesim.png", b, NULL); 		\
	enesim_renderer_unref(rc); 					\
	enesim_buffer_unref(b); 					\
	enesim_surface_unref(s)

#define TEST(t) { #t, t ## _enesim, t ## _cairo }

typedef struct
{
	char *name;
	void (*e)();
	void (*c)();
} test;

static double _time_get(void)
{
	struct timeval timev;

	gettimeofday(&timev, NULL);
	return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);

}

static void arc_enesim()
{
	ENESIM_BEGIN(256, 256);

	Enesim_Renderer *r;
	Enesim_Renderer_Compound_Layer *l;
	Enesim_Path *p;
	double xc;
	double yc;
	double radius;
	double angle1;
	double angle2;

	xc = 128.0;
	yc = 128.0;
	radius = 100.0;
	angle1 = 45.0 * (M_PI / 180.0);
	angle2 = 180.0 * (M_PI / 180.0);

	rc = enesim_renderer_compound_new();

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, xc + radius * cos(angle1), yc + radius * sin(angle1));
	enesim_path_arc_to(p, radius, radius, 0.0, EINA_FALSE, EINA_TRUE, xc + radius * cos(angle2), yc + radius * sin(angle2));
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 10);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_circle_new();
	enesim_renderer_circle_center_set(r, xc, yc);
	enesim_renderer_circle_radius_set(r, 10);
	enesim_renderer_shape_fill_color_set(r, 0x99991f1f);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_FILL);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, xc, yc);
	enesim_path_line_to(p, xc + radius * cos(angle1), yc + radius * sin(angle1));
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 6);
	enesim_renderer_shape_stroke_color_set(r, 0x99991f1f);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, xc, yc);
	enesim_path_line_to(p, xc + radius * cos(angle2), yc + radius * sin(angle2));
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 6);
	enesim_renderer_shape_stroke_color_set(r, 0x99991f1f);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	ENESIM_END(arc);
}

static void arc_cairo()
{
	CAIRO_BEGIN(256, 256);

	double xc;
	double yc;
	double radius;
	double angle1;
	double angle2;

	xc = 128.0;
	yc = 128.0;
	radius = 100.0;
	angle1 = 45.0 * (M_PI / 180.0);
	angle2 = 180.0 * (M_PI / 180.0);

	cairo_set_line_width (cr, 10.0);
	cairo_arc (cr, xc, yc, radius, angle1, angle2);
	cairo_stroke (cr);

	cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
	cairo_set_line_width (cr, 6.0);

	cairo_arc (cr, xc, yc, 10.0, 0, 2*M_PI);
	cairo_fill (cr);

	cairo_arc (cr, xc, yc, radius, angle1, angle1);
	cairo_line_to (cr, xc, yc);
	cairo_arc (cr, xc, yc, radius, angle2, angle2);
	cairo_line_to (cr, xc, yc);
	cairo_stroke (cr);

	CAIRO_END(arc);
}

static void arc_negative_enesim()
{
	ENESIM_BEGIN(256, 256);

	Enesim_Renderer *r;
	Enesim_Renderer_Compound_Layer *l;
	Enesim_Path *p;
	double xc;
	double yc;
	double radius;
	double angle1;
	double angle2;

	xc = 128.0;
	yc = 128.0;
	radius = 100.0;
	angle1 = 45.0 * (M_PI / 180.0);
	angle2 = 180.0 * (M_PI / 180.0);

	rc = enesim_renderer_compound_new();

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, xc + radius * cos(angle1), yc + radius * sin(angle1));
	enesim_path_arc_to(p, radius, radius, 0.0, EINA_TRUE, EINA_FALSE, xc + radius * cos(angle2), yc + radius * sin(angle2));
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 10);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_FILL);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_circle_new();
	enesim_renderer_circle_center_set(r, xc, yc);
	enesim_renderer_circle_radius_set(r, 10);
	enesim_renderer_shape_fill_color_set(r, 0x99991f1f);
        enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_FILL);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, xc, yc);
	enesim_path_line_to(p, xc + radius * cos(angle1), yc + radius * sin(angle1));
	enesim_path_unref(p);
        enesim_renderer_shape_stroke_weight_set(r, 6);
        enesim_renderer_shape_stroke_color_set(r, 0x99991f1f);
        enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, xc, yc);
	enesim_path_line_to(p, xc + radius * cos(angle2), yc + radius * sin(angle2));
	enesim_path_unref(p);
        enesim_renderer_shape_stroke_weight_set(r, 6);
        enesim_renderer_shape_stroke_color_set(r, 0x99991f1f);
        enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	ENESIM_END(arc_negative);
}

static void arc_negative_cairo()
{
	CAIRO_BEGIN(256, 256);

	double xc;
	double yc;
	double radius;
	double angle1;
	double angle2;

	xc = 128.0;
	yc = 128.0;
	radius = 100.0;
	angle1 = 45.0 * (M_PI / 180.0);
	angle2 = 180.0 * (M_PI / 180.0);

	cairo_set_line_width (cr, 10.0);
	cairo_arc_negative (cr, xc, yc, radius, angle1, angle2);
	cairo_stroke (cr);

	cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
	cairo_set_line_width (cr, 6.0);

	cairo_arc (cr, xc, yc, 10.0, 0, 2*M_PI);
	cairo_fill (cr);

	cairo_arc (cr, xc, yc, radius, angle1, angle1);
	cairo_line_to (cr, xc, yc);
	cairo_arc (cr, xc, yc, radius, angle2, angle2);
	cairo_line_to (cr, xc, yc);
	cairo_stroke (cr);

	CAIRO_END(arc_negative);
}

static void clip_enesim()
{
	ENESIM_BEGIN(256, 256);

	Enesim_Renderer *r;
	Enesim_Renderer *rcc;
	Enesim_Renderer_Compound_Layer *l;
	Enesim_Path *p;

	rcc = enesim_renderer_compound_new();

        r = enesim_renderer_rectangle_new();
        enesim_renderer_rectangle_position_set(r, 0, 0);
        enesim_renderer_rectangle_size_set(r, 256, 256);
        enesim_renderer_shape_fill_color_set(r, 0xff000000);
        enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_FILL);
        l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_FILL);
        enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rcc, l);

        r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
        enesim_path_move_to(p, 0, 0);
        enesim_path_line_to(p, 256, 256);
        enesim_path_move_to(p, 256, 0);
        enesim_path_line_to(p, 0, 256);
	enesim_path_unref(p);
        enesim_renderer_shape_stroke_weight_set(r, 10);
        enesim_renderer_shape_stroke_color_set(r, 0xff00ff00);
        enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
        l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
        enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rcc, l);

        rc = enesim_renderer_circle_new();
        enesim_renderer_circle_center_set(rc, 128, 128);
        enesim_renderer_circle_radius_set(rc, 76.8);
        enesim_renderer_shape_fill_renderer_set(rc, rcc);
        enesim_renderer_shape_draw_mode_set(rc, ENESIM_RENDERER_SHAPE_DRAW_MODE_FILL);

	ENESIM_END(clip);
}

static void clip_cairo()
{
	CAIRO_BEGIN(256, 256);

	cairo_arc (cr, 128.0, 128.0, 76.8, 0, 2 * M_PI);
	cairo_clip (cr);

	cairo_new_path (cr);
	cairo_rectangle (cr, 0, 0, 256, 256);
	cairo_fill (cr);
	cairo_set_source_rgb (cr, 0, 1, 0);
	cairo_move_to (cr, 0, 0);
	cairo_line_to (cr, 256, 256);
	cairo_move_to (cr, 256, 0);
	cairo_line_to (cr, 0, 256);
	cairo_set_line_width (cr, 10.0);
	cairo_stroke (cr);

	CAIRO_END(clip);
}

static void curve_to_enesim()
{
	ENESIM_BEGIN(256, 256);

	Enesim_Renderer *r;
	Enesim_Renderer_Compound_Layer *l;
	Enesim_Path *p;
	double x;
	double y;
	double x1;
	double yy1;
	double x2;
	double y2;
	double x3;
	double y3;

	x=25.6;
	y=128.0;
	x1=102.4;
	yy1=230.4;
	x2=153.6;
	y2=25.6;
	x3=230.4;
	y3=128.0;

	rc = enesim_renderer_compound_new();

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, x, y);
	enesim_path_cubic_to(p, x1, yy1, x2, y2, x3, y3);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 10);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_FILL);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, x, y);
	enesim_path_line_to(p, x1, yy1);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 6);
	enesim_renderer_shape_stroke_color_set(r, 0x99991f1f);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, x2, y2);
	enesim_path_line_to(p, x3, y3);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 6);
	enesim_renderer_shape_stroke_color_set(r, 0x99991f1f);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	ENESIM_END(curve_to);
}

static void curve_to_cairo()
{
	CAIRO_BEGIN(256, 256);

	double x;
	double y;
	double x1;
	double yy1;
	double x2;
	double y2;
	double x3;
	double y3;

	x=25.6;
	y=128.0;
	x1=102.4;
	yy1=230.4;
	x2=153.6;
	y2=25.6;
	x3=230.4;
	y3=128.0;

	cairo_move_to (cr, x, y);
	cairo_curve_to (cr, x1, yy1, x2, y2, x3, y3);

	cairo_set_line_width (cr, 10.0);
	cairo_stroke (cr);

	cairo_set_source_rgba (cr, 1, 0.2, 0.2, 0.6);
	cairo_set_line_width (cr, 6.0);
	cairo_move_to (cr,x,y);   cairo_line_to (cr,x1,yy1);
	cairo_move_to (cr,x2,y2); cairo_line_to (cr,x3,y3);
	cairo_stroke (cr);

	CAIRO_END(curve_to);
}

static void fill_stroke_enesim()
{
	ENESIM_BEGIN(256, 256);

	Enesim_Renderer *r;
	Enesim_Renderer_Compound_Layer *l;
	Enesim_Path *p;

	rc = enesim_renderer_compound_new();

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 128.0, 25.6);
	enesim_path_line_to(p, 230.4, 230.4);
	enesim_path_line_to(p, 128.0, 230.4);
	enesim_path_cubic_to(p, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0);
	enesim_path_close(p);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 10);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_fill_color_set(r, 0xff0000ff);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE_FILL);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_FILL);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 64.0, 25.6);
	enesim_path_line_to(p, 115.2, 76.8);
	enesim_path_line_to(p, 64.0, 128.0);
	enesim_path_line_to(p, 12.8, 76.8);
	enesim_path_close(p);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 10);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_fill_color_set(r, 0xff0000ff);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE_FILL);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	ENESIM_END(fill_stroke);
}

static void fill_stroke_cairo()
{
	CAIRO_BEGIN(256, 256);

	cairo_move_to (cr, 128.0, 25.6);
	cairo_line_to (cr, 230.4, 230.4);
	cairo_rel_line_to (cr, -102.4, 0.0);
	cairo_curve_to (cr, 51.2, 230.4, 51.2, 128.0, 128.0, 128.0);
	cairo_close_path (cr);

	cairo_move_to (cr, 64.0, 25.6);
	cairo_rel_line_to (cr, 51.2, 51.2);
	cairo_rel_line_to (cr, -51.2, 51.2);
	cairo_rel_line_to (cr, -51.2, -51.2);
	cairo_close_path (cr);

	cairo_set_line_width (cr, 10.0);
	cairo_set_source_rgb (cr, 0, 0, 1);
	cairo_fill_preserve (cr);
	cairo_set_source_rgb (cr, 0, 0, 0);
	cairo_stroke (cr);

	CAIRO_END(fill_stroke);
}

static void set_line_cap_enesim()
{
	ENESIM_BEGIN(256, 256);

	Enesim_Renderer *r;
	Enesim_Renderer_Compound_Layer *l;
	Enesim_Path *p;

	rc = enesim_renderer_compound_new();

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 64.0, 50.0);
	enesim_path_line_to(p, 64.0, 200.0);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_cap_set(r, ENESIM_RENDERER_SHAPE_STROKE_CAP_BUTT);
	enesim_renderer_shape_stroke_weight_set(r, 30.0);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 128.0, 50.0);
	enesim_path_line_to(p, 128.0, 200.0);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_cap_set(r, ENESIM_RENDERER_SHAPE_STROKE_CAP_ROUND);
	enesim_renderer_shape_stroke_weight_set(r, 30.0);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 192.0, 50.0);
	enesim_path_line_to(p, 192.0, 200.0);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_cap_set(r, ENESIM_RENDERER_SHAPE_STROKE_CAP_SQUARE);
	enesim_renderer_shape_stroke_weight_set(r, 30.0);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 64.0, 50.0);
	enesim_path_line_to(p, 64.0, 200.0);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 2.56);
	enesim_renderer_shape_stroke_color_set(r, 0x99991f1f);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 128.0, 50.0);
	enesim_path_line_to(p, 128.0, 200.0);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 2.56);
	enesim_renderer_shape_stroke_color_set(r, 0x99991f1f);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 192.0, 50.0);
	enesim_path_line_to(p, 192.0, 200.0);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_weight_set(r, 2.56);
	enesim_renderer_shape_stroke_color_set(r, 0x99991f1f);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	ENESIM_END(set_line_cap);
}

static void set_line_cap_cairo()
{
	CAIRO_BEGIN(256, 256);

	cairo_set_line_width (cr, 30.0);
	cairo_set_line_cap  (cr, CAIRO_LINE_CAP_BUTT); /* default */
	cairo_move_to (cr, 64.0, 50.0); cairo_line_to (cr, 64.0, 200.0);
	cairo_stroke (cr);
	cairo_set_line_cap  (cr, CAIRO_LINE_CAP_ROUND);
	cairo_move_to (cr, 128.0, 50.0); cairo_line_to (cr, 128.0, 200.0);
	cairo_stroke (cr);
	cairo_set_line_cap  (cr, CAIRO_LINE_CAP_SQUARE);
	cairo_move_to (cr, 192.0, 50.0); cairo_line_to (cr, 192.0, 200.0);
	cairo_stroke (cr);

	cairo_set_source_rgb (cr, 1, 0.2, 0.2);
	cairo_set_line_width (cr, 2.56);
	cairo_move_to (cr, 64.0, 50.0); cairo_line_to (cr, 64.0, 200.0);
	cairo_move_to (cr, 128.0, 50.0);  cairo_line_to (cr, 128.0, 200.0);
	cairo_move_to (cr, 192.0, 50.0); cairo_line_to (cr, 192.0, 200.0);
	cairo_stroke (cr);

	CAIRO_END(set_line_cap);
}

static void set_line_join_enesim()
{
	ENESIM_BEGIN(256, 256);

	Enesim_Renderer *r;
	Enesim_Renderer_Compound_Layer *l;
	Enesim_Path *p;

	rc = enesim_renderer_compound_new();

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 76.8, 84.48);
	enesim_path_line_to(p, 128.0, 33.28);
	enesim_path_line_to(p, 179.2, 84.48);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_join_set(r, ENESIM_RENDERER_SHAPE_STROKE_JOIN_MITER);
	enesim_renderer_shape_stroke_weight_set(r, 40.96);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 76.8, 161.28);
	enesim_path_line_to(p, 128.0, 110.08);
	enesim_path_line_to(p, 179.2, 161.28);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_join_set(r, ENESIM_RENDERER_SHAPE_STROKE_JOIN_BEVEL);
	enesim_renderer_shape_stroke_weight_set(r, 40.96);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	r = enesim_renderer_path_new();
	enesim_renderer_path_path_get(r, &p);
	enesim_path_move_to(p, 76.8, 238.08);
	enesim_path_line_to(p, 128.0, 186.88);
	enesim_path_line_to(p, 179.2, 238.08);
	enesim_path_unref(p);
	enesim_renderer_shape_stroke_join_set(r, ENESIM_RENDERER_SHAPE_STROKE_JOIN_ROUND);
	enesim_renderer_shape_stroke_weight_set(r, 40.96);
	enesim_renderer_shape_stroke_color_set(r, 0xff000000);
	enesim_renderer_shape_draw_mode_set(r, ENESIM_RENDERER_SHAPE_DRAW_MODE_STROKE);
	l = enesim_renderer_compound_layer_new();
	enesim_renderer_compound_layer_rop_set(l, ENESIM_ROP_BLEND);
	enesim_renderer_compound_layer_renderer_set(l, r);
	enesim_renderer_compound_layer_add(rc, l);

	ENESIM_END(set_line_join);
}

static void set_line_join_cairo()
{
	CAIRO_BEGIN(256, 256);

	cairo_set_line_width (cr, 40.96);
	cairo_move_to (cr, 76.8, 84.48);
	cairo_rel_line_to (cr, 51.2, -51.2);
	cairo_rel_line_to (cr, 51.2, 51.2);
	cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER); /* default */
	cairo_stroke (cr);

	cairo_move_to (cr, 76.8, 161.28);
	cairo_rel_line_to (cr, 51.2, -51.2);
	cairo_rel_line_to (cr, 51.2, 51.2);
	cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL);
	cairo_stroke (cr);

	cairo_move_to (cr, 76.8, 238.08);
	cairo_rel_line_to (cr, 51.2, -51.2);
	cairo_rel_line_to (cr, 51.2, 51.2);
	cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
	cairo_stroke (cr);

	CAIRO_END(set_line_join);
}


static void circle_enesim()
{
	ENESIM_BEGIN(256, 256);

	Enesim_Path *p;

	rc = enesim_renderer_path_new();
	enesim_renderer_path_path_get(rc, &p);
	enesim_path_move_to(p, 128, 128 - 78);
	enesim_path_arc_to(p, 78, 78, 0, EINA_FALSE, EINA_TRUE, 128, 128 + 78);
	enesim_path_arc_to(p, 78, 78, 0, EINA_FALSE, EINA_TRUE, 128, 128 - 78);
	enesim_path_unref(p);
	enesim_renderer_shape_fill_color_set(rc, 0xff000000);
	enesim_renderer_shape_draw_mode_set(rc, ENESIM_RENDERER_SHAPE_DRAW_MODE_FILL);

//        rc = enesim_renderer_circle_new();
//        enesim_renderer_circle_center_set(rc, 128, 128);
//        enesim_renderer_circle_radius_set(rc, 78);

	ENESIM_END(circle);
}

static void circle_cairo()
{
	CAIRO_BEGIN(256, 256);

	cairo_arc (cr, 128, 128, 78, 0, 2 * M_PI);
	cairo_fill (cr);

	CAIRO_END(circle);
}

test tests[] =
{
	TEST(arc),
	TEST(arc_negative),
	TEST(clip),
	TEST(curve_to),
	TEST(fill_stroke),
	TEST(set_line_cap),
	TEST(set_line_join),
	TEST(circle),
	{ NULL, NULL, NULL }
};

int main()
{
	int i;

	enesim_init();

	for (i = 0; tests[i].name != NULL; i++)
	{
		printf("test %s\n", tests[i].name);
		tests[i].c();
		tests[i].e();
	}

	enesim_shutdown();

	return 0;
}
